package com.jike.jkgame.db;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.jike.jkgame.JKApp;
import com.jike.jkgame.Utilis;
import com.jike.jkgame.data.City;
import com.jike.jkgame.data.Equipment;
import com.jike.jkgame.data.Event;
import com.jike.jkgame.data.Fragment;
import com.jike.jkgame.data.General;
import com.jike.jkgame.data.MiscUpper;
import com.jike.jkgame.data.Mission;
import com.jike.jkgame.data.RewardItem;
import com.jike.jkgame.data.Skill;
import com.jike.jkgame.data.Treasure;
import com.jike.jkgame.data.Treasure.NeededFragment;

public class ResourcesDAO {

	private SQLiteDatabase mDatabase;
	private ResourceSQLiteHelper mDBHelper;

	private static ResourcesDAO mInstance;

	public static ResourcesDAO get() {
		if (mInstance == null) {
			mInstance = new ResourcesDAO(JKApp.get());
			mInstance.open();
		}

		return mInstance;
	}

	private ResourcesDAO(Context context) {
		mDBHelper = new ResourceSQLiteHelper(context);
	}

	private void open() {
		if (mDatabase == null || !mDatabase.isOpen()) {
			mDatabase = mDBHelper.getWritableDatabase();
		}
	}

	public void close() {
		mDBHelper.close();
	}

	public int getDataFileVersion(int magic) {
		Cursor cursor = mDatabase.query(DataFilesTable.TABLE_NAME, null,
				"magic = ?", new String[] { String.valueOf(magic) }, null,
				null, null);
		
		cursor.moveToFirst();
		
		if (cursor.isAfterLast()) {
			return -1;
		}
		
		int version = cursor.getInt(2);
		cursor.close();
		return version;
	}
	
	public void updateDataFileVersion(int magic, int version) {
		ContentValues v = new ContentValues();
		v.put("magic", magic);
		v.put("version", version);
		int line = mDatabase.update(DataFilesTable.TABLE_NAME, v, "magic = ?", new String[] {String.valueOf(magic)});
		if (line <= 0) {
			mDatabase.insert(DataFilesTable.TABLE_NAME, null, v);
		}
	}

	public int insertMission(List<Mission> missions) {
		int count = 0;
		for (Mission mission : missions) {
			long id = insertMission(mission);
			if (id >= 0) {
				count++;
			}
		}
		return count;
	}

	public long insertMission(Mission mission) {
		if (mission == null) {
			return -1;
		}

		ContentValues values = new ContentValues();
		values.put("id", mission.id);
		values.put("parentid", mission.parentId);
		values.put("name", mission.name);
		values.put("descript", mission.descript);
		values.put("energy", mission.energy);
		values.put("level", mission.level);
		values.put("completeness", mission.completeness);
		values.put("reward_exp", mission.reward_exp);
		values.put("reward_cash", mission.reward_cash);
		values.put("random_reward_Item_count", mission.random_reward_Item_count);
		values.put("random_reward_item",
				Utilis.arrayToString(mission.random_reward_item));
		values.put("button", mission.buttonStr);
		values.put("animation", mission.animation);
		long insertId = mDatabase.insert(MissionTable.TABLE_NAME, null, values);
		return insertId;
	}

	public int deleteMission(Long id) {
		return mDatabase.delete(MissionTable.TABLE_NAME, "id = ?",
				new String[] { String.valueOf(id) });
	}

	public List<Mission> getAllMissions(int parentId) {
		List<Mission> missions = new ArrayList<Mission>();
		Cursor cursor = mDatabase.query(MissionTable.TABLE_NAME, null,
				"parentid = ?", new String[] { String.valueOf(parentId) },
				null, null, " _id asc");

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Mission mission = cursorToMission(cursor);
			missions.add(mission);
			cursor.moveToNext();
		}
		cursor.close();

		return missions;
	}

	public int clearMissions() {
		int cnt = 0;
		cnt += mDatabase.delete(MissionTable.TABLE_NAME, null, null);
		cnt += mDatabase.delete(EventsTable.TABLE_NAME, null, null);
		cnt += mDatabase.delete(CitiesTable.TABLE_NAME, null, null);
		return cnt;
	}

	public static Mission cursorToMission(Cursor cursor) {
		Mission mission = new Mission();
		mission.id = cursor.getInt(1);
		mission.parentId = cursor.getInt(2);
		mission.name = cursor.getString(3);
		mission.descript = cursor.getString(4);
		mission.energy = cursor.getInt(5);
		mission.level = cursor.getInt(6);
		mission.completeness = cursor.getInt(7);
		mission.reward_exp = cursor.getInt(8);
		mission.reward_cash = cursor.getInt(9);
		mission.random_reward_Item_count = cursor.getInt(10);
		mission.random_reward_item = RewardItem.stringToRewardItemArray(cursor
				.getString(11));
		mission.buttonStr = cursor.getString(12);
		mission.animation = cursor.getInt(13);
		return mission;
	}

	public static City cursorToCity(Cursor cursor) {
		City m = new City();
		m.id = cursor.getInt(1);
		m.name = cursor.getString(2);
		return m;
	}

	public static Event cursorToEvent(Cursor cursor) {
		Event m = new Event();
		m.id = cursor.getInt(1);
		m.name = cursor.getString(2);
		m.parentId = cursor.getInt(4);
		return m;
	}

	public City getMission1Level(int id) {
		Cursor cursor = mDatabase.query(CitiesTable.TABLE_NAME, null, "id = ?",
				new String[] { String.valueOf(id) }, null, null, null);

		City m = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			m = cursorToCity(cursor);
		}
		cursor.close();

		return m;
	}

	public long insertCity(City mission) {
		if (mission == null) {
			return -1;
		}

		ContentValues values = new ContentValues();
		values.put("id", mission.id);
		values.put("name", mission.name);
		long insertId = mDatabase.insert(CitiesTable.TABLE_NAME, null, values);
		return insertId;
	}

	public long insertEvent(Event mission) {
		if (mission == null) {
			return -1;
		}

		ContentValues values = new ContentValues();
		values.put("id", mission.id);
		values.put("name", mission.name);
		values.put("parentid", mission.parentId);
		long insertId = mDatabase.insert(EventsTable.TABLE_NAME, null, values);
		return insertId;
	}

	public List<City> getAllCities() {
		List<City> missions = new ArrayList<City>();
		Cursor cursor = mDatabase.query(CitiesTable.TABLE_NAME, null, null,
				null, null, null, " _id asc");

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			City mission = cursorToCity(cursor);
			missions.add(mission);
			cursor.moveToNext();
		}
		cursor.close();

		return missions;

	}

	public List<Event> getAllEvents(int parentId) {
		List<Event> missions = new ArrayList<Event>();
		Cursor cursor = mDatabase.query(EventsTable.TABLE_NAME, null,
				"parentid = ?", new String[] { String.valueOf(parentId) },
				null, null, " _id asc");

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Event mission = cursorToEvent(cursor);
			missions.add(mission);
			cursor.moveToNext();
		}
		cursor.close();

		return missions;

	}

	public Event getMission2Level(int id) {
		Cursor cursor = mDatabase.query(EventsTable.TABLE_NAME, null, "id = ?",
				new String[] { String.valueOf(id) }, null, null, null);

		Event m = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			m = cursorToEvent(cursor);
		}
		cursor.close();

		return m;
	}

	public long insertEquipment(Equipment equip) {
		if (equip == null) {
			return -1;
		}

		ContentValues values = new ContentValues();
		values.put("id", equip.id);
		values.put("type", equip.type);
		values.put("name", equip.name);
		values.put("descript", equip.descript);
		values.put("star_level", equip.star_level);
		values.put("attack_min", equip.attack_min);
		values.put("attack_max", equip.attack_max);
		values.put("defense_min", equip.defense_min);
		values.put("defense_max", equip.defense_max);
		values.put("energy_recover_min", equip.energy_recover_min);
		values.put("energy_recover_max", equip.energy_recover_max);
		values.put("ammo_recover_min", equip.ammo_recover_min);
		values.put("ammo_recover_max", equip.ammo_recover_max);
		values.put("exp_addon_min", equip.exp_addon_min);
		values.put("exp_addon_max", equip.exp_addon_max);
		values.put("money_addon_min", equip.money_addon_min);
		values.put("money_addon_max", equip.money_addon_max);
		long insertId = mDatabase.insert(EquipmentsTable.TABLE_NAME, null,
				values);
		return insertId;
	}

	private Equipment cursorToEquipment(Cursor cursor) {
		Equipment e = new Equipment();
		e.id = cursor.getInt(1);
		e.type = (byte) cursor.getInt(2);
		e.name = cursor.getString(3);
		e.descript = cursor.getString(4);
		e.star_level = (byte) cursor.getInt(5);
		e.attack_min = cursor.getInt(6);
		e.attack_max = cursor.getInt(7);
		e.defense_min = cursor.getInt(8);
		e.defense_max = cursor.getInt(9);
		e.energy_recover_min = (byte) cursor.getInt(10);
		e.energy_recover_max = (byte) cursor.getInt(11);
		e.ammo_recover_min = (byte) cursor.getInt(12);
		e.ammo_recover_max = (byte) cursor.getInt(13);
		e.exp_addon_min = (byte) cursor.getInt(14);
		e.exp_addon_max = (byte) cursor.getInt(15);
		e.money_addon_min = (byte) cursor.getInt(16);
		e.money_addon_max = (byte) cursor.getInt(17);
		return e;
	}

	public Equipment getEquipment(int id) {
		Cursor cursor = mDatabase
				.query(EquipmentsTable.TABLE_NAME, null, "id = ?",
						new String[] { String.valueOf(id) }, null, null, null);

		Equipment e = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			e = cursorToEquipment(cursor);
		}
		cursor.close();

		return e;
	}

	public int clearEquipments() {
		return mDatabase.delete(EquipmentsTable.TABLE_NAME, null, null);
	}

	public long insertGeneral(General g) {
		if (g == null) {
			return -1;
		}

		ContentValues v = new ContentValues();
		v.put("id", g.id);
		v.put("name", g.name);
		v.put("descript", g.description);
		v.put("star_level", g.star_level);
		v.put("country", g.country);
		v.put("attack", g.attack);
		v.put("attack_range", g.attack_range);
		v.put("defense", g.defense);
		v.put("defense_range", g.defense_range);
		v.put("attack_addon", g.attack_addon);
		v.put("defense_addon", g.defense_addon);
		v.put("skill", Utilis.intArrayToString(g.skillIds));

		long id = mDatabase.insert(GeneralsTable.TABLE_NAME, null, v);
		return id;
	}

	private General cursorToGeneral(Cursor cursor) {
		General g = new General();
		g.id = cursor.getInt(1);
		g.name = cursor.getString(2);
		g.description = cursor.getString(3);
		g.star_level = (byte) cursor.getInt(4);
		g.country = (byte) cursor.getInt(5);
		g.attack = cursor.getInt(6);
		g.attack_range = (byte) cursor.getInt(7);
		g.defense = cursor.getInt(8);
		g.defense_range = (byte) cursor.getInt(9);
		g.attack_addon = cursor.getInt(10);
		g.defense_addon = cursor.getInt(11);
		g.skillIds = Utilis.stringToIntArray(cursor.getString(12));

		return g;
	}

	public General getGeneral(int id) {
		Cursor cursor = mDatabase
				.query(GeneralsTable.TABLE_NAME, null, "id = ?",
						new String[] { String.valueOf(id) }, null, null, null);

		General g = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			g = cursorToGeneral(cursor);
		}
		cursor.close();

		return g;
	}
	
	public int clearGenerals() {
		return mDatabase.delete(GeneralsTable.TABLE_NAME, null, null);
	}
	
	public long insertSkill(Skill s) {
		if (s == null) {
			return -1;
		}
		
		ContentValues v = new ContentValues();
		v.put("id", s.id);
		v.put("descript", s.descript);
		v.put("attack_addon", s.attack_addon);
		v.put("defense_addon", s.defense_addon);
		v.put("strength_addon", s.strength_addon);
		v.put("country", s.country);
		v.put("country_addon", s.country_addon);
		v.put("opponent", s.opponent);
		v.put("opponent_addon", s.opponent_addon);
		v.put("condition", Utilis.arrayToString(s.condition));
		
		long id = mDatabase.insert(SkillsTable.TABLE_NAME, null, v);
		return id;
		
	}
	
	public Skill cursorToSkill(Cursor cursor) {
		Skill s = new Skill();
		s.id = cursor.getInt(1);
		s.descript = cursor.getString(2);
		s.attack_addon = (byte) cursor.getInt(3);
		s.defense_addon = (byte) cursor.getInt(4);
		s.strength_addon = (byte) cursor.getInt(5);
		s.country = (byte) cursor.getInt(6);
		s.country_addon = (byte) cursor.getInt(7);
		s.opponent = (byte) cursor.getInt(8);
		s.opponent_addon = (byte) cursor.getInt(9);
		s.condition = Skill.SkillCondition.stringToArray(cursor.getString(10));
		return s;
	}
	
	public Skill getSkill(int id) {
		Cursor cursor = mDatabase
				.query(SkillsTable.TABLE_NAME, null, "id = ?",
						new String[] { String.valueOf(id) }, null, null, null);

		Skill s = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			s = cursorToSkill(cursor);
		}
		cursor.close();

		return s;
	}
	
	public int clearSkills() {
		return mDatabase.delete(SkillsTable.TABLE_NAME, null, null);
	}
	
	public long insertFragment(Fragment f) {
		if (f == null) {
			return -1;
		}
		
		ContentValues v = new ContentValues();
		v.put("id", f.id);
		v.put("name", f.name);
		v.put("descript", f.description);
		
		long id = mDatabase.insert(FragmentsTable.TABLE_NAME, null, v);
		
		return id;
	}
	
	private Fragment cursorToFragment(Cursor cursor) {
		Fragment f = new Fragment();
		
		f.id = cursor.getInt(1);
		f.name = cursor.getString(2);
		f.description = cursor.getString(3);
		
		return f;
	}
	
	public Fragment getFragment(int id) {
		Cursor cursor = mDatabase
				.query(FragmentsTable.TABLE_NAME, null, "id = ?",
						new String[] { String.valueOf(id) }, null, null, null);

		Fragment f = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			f = cursorToFragment(cursor);
		}
		cursor.close();

		return f;
	}
	
	public int clearFragments() {
		return mDatabase.delete(FragmentsTable.TABLE_NAME, null, null);
	}
	
	public long insertTreasure(Treasure t) {
		if (t == null) {
			return -1;
		}
		
		ContentValues v = new ContentValues();
		v.put("id", t.id);
		v.put("name", t.name);
		v.put("descript", t.description);
		v.put("max_attack_addon_min", t.max_attack_addon_min);
		v.put("max_attack_addon_max", t.max_attack_addon_max);
		v.put("min_attack_addon_min", t.min_attack_addon_min);
		v.put("min_attack_addon_max", t.min_attack_addon_max);
		v.put("max_defense_addon_min", t.max_defense_addon_min);
		v.put("max_defense_addon_max", t.max_defense_addon_max);
		v.put("min_defense_addon_min", t.min_defense_addon_min);
		v.put("min_defense_addon_max", t.min_defense_addon_max);
		v.put("max_attack_probability_min", t.max_attack_probability_min);
		v.put("max_attack_probability_max", t.max_attack_probability_max);
		v.put("max_defense_probability_min", t.max_defense_probability_min);
		v.put("max_defense_probability_max", t.max_defense_probability_max);
		v.put("needed_fragments", Utilis.arrayToString(t.needed_fragments));
		
		long id = mDatabase.insert(TreasuresTable.TABLE_NAME, null, v);
		
		return id;
	}
	
	private Treasure cursorToTreasure(Cursor cursor) {
		Treasure t = new Treasure();
		t.id = cursor.getInt(1);
		t.name = cursor.getString(2);
		t.description = cursor.getString(3);
		t.max_attack_addon_min = (byte) cursor.getInt(4);
		t.max_attack_addon_max = (byte) cursor.getInt(5);
		t.min_attack_addon_min = (byte) cursor.getInt(6);
		t.min_attack_addon_max = (byte) cursor.getInt(7);
		t.max_defense_addon_min = (byte) cursor.getInt(8);
		t.max_defense_addon_max = (byte) cursor.getInt(9);
		t.min_defense_addon_min = (byte) cursor.getInt(10);
		t.min_defense_addon_max = (byte) cursor.getInt(11);
		t.max_attack_probability_min = (byte) cursor.getInt(12);
		t.max_attack_probability_max = (byte) cursor.getInt(13);
		t.max_defense_probability_min = (byte) cursor.getInt(14);
		t.max_defense_probability_max = (byte) cursor.getInt(15);
		t.needed_fragments = NeededFragment.stringToArray(cursor.getString(16));
		return t;
	}
	
	public Treasure getTreasure(int id) {
		Cursor cursor = mDatabase
				.query(TreasuresTable.TABLE_NAME, null, "id = ?",
						new String[] { String.valueOf(id) }, null, null, null);

		Treasure t = null;
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			t = cursorToTreasure(cursor);
		}
		cursor.close();

		return t;
	}
	
	public int clearTreasures() {
		return mDatabase.delete(TreasuresTable.TABLE_NAME, null, null);
	}
	
	public long insertMiscUpper(MiscUpper upper) {
		if (upper == null) {
			return -1;
		}
		
		ContentValues v = new ContentValues();
		v.put("level", upper.level);
		v.put("exp_upper", upper.exp);
		v.put("energy_upper", upper.energy);
		v.put("ammo_upper", upper.ammo);
		v.put("team_upper", upper.team);
		v.put("friend_upper", upper.friend);
		long id = mDatabase.insert(MiscUpperTable.TABLE_NAME, null, v);
		
		return id;
	}
	
	private static MiscUpper cursorToMiscUpper(Cursor cursor) {
		MiscUpper upper = new MiscUpper();
		upper.level = cursor.getInt(1);
		upper.exp = cursor.getInt(2);
		upper.energy = cursor.getInt(3);
		upper.ammo = cursor.getInt(4);
		upper.team = cursor.getInt(5);
		upper.friend = cursor.getInt(6);
		
		return upper;
	}
	
	public MiscUpper getMiscUpper(int level) {
		Cursor cursor = mDatabase.query(MiscUpperTable.TABLE_NAME, null, "level = ?", new String[]{String.valueOf(level)}, null, null, null);
		cursor.moveToFirst();
		if (!cursor.isAfterLast()) {
			return cursorToMiscUpper(cursor);
		}
		
		return null;
	}
	
	public int clearMiscUpper() {
		return mDatabase.delete(MiscUpperTable.TABLE_NAME, null, null);
	}

}
